from datetime import timedelta
from django.utils import timezone
import pendulum


def now():
    return pendulum.instance(timezone.now())


def start_of_week(moment=None):
    """ Return the date start of week, when week start on Sunday
        Input can be a date or datetime
    """
    moment = moment or now()
    us_weekday = moment.isoweekday() % 7
    today = moment.replace(hour=0, minute=0, second=0, microsecond=0)
    start = today - timedelta(days=us_weekday)
    return start


def end_of_week(moment=None):
    """ Return the date end of week, when week start on Sunday
        Input can be a date or datetime
    """
    moment = moment or now()
    us_weekday = moment.isoweekday() % 7
    today = moment.replace(hour=23, minute=59, second=59, microsecond=999999)
    end = today + timedelta(days=(6 - us_weekday))
    return end


def range_of_us_week(moment=None):
    moment = moment or now()
    start_date = start_of_week(moment)
    end_date = end_of_week(moment)

    return [start_date, end_date]


def get_time_range(unit='day', moment=None):
    moment = pendulum.instance(moment or now())
    return [moment.start_of(unit), moment.end_of(unit)]


def get_starting_time_range(unit='day', moment=None):
    moment = pendulum.instance(moment or now())
    return [moment.start_of(unit), moment.now()]


def range_of_week_specific_date(date, moment=None):
    start_date = pendulum.parse(date.strftime('%Y-%m-%d')).start_of('week')
    end_date = pendulum.parse(date.strftime('%Y-%m-%d')).end_of('week')

    return [start_date, end_date]


def start_of_month(date, moment=None):
    start_date = pendulum.parse(date.strftime('%Y-%m-%d')).start_of('month')

    return start_date


def end_of_month(date, moment=None):
    end_date = pendulum.parse(date.strftime('%Y-%m-%d')).end_of('month')
    return end_date


def range_of_us_current_month(moment=None):
    moment = pendulum.instance(moment or now())
    start_of_month = moment.start_of('month')
    end_of_month = moment.end_of('month')

    return [start_of_month, end_of_month]


def range_of_us_next_month(moment=None):
    moment = pendulum.instance(moment or now())
    moment = moment.add(months=1)
    start_of_next_month = moment.start_of('month')
    end_of_next_month = moment.end_of('month')
    return [start_of_next_month, end_of_next_month]
